//	ID : pallab81
// 	PROG : 10946
// 	LANG : C++
// 	2011-07-05-15.01.51 Tuesday
//
// 	"I have not failed, I have just found 10000 ways that won't work.
//


#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>

#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cstring>

using namespace std;

#define fo(i,ed) for(int i = 0 ; i < ed ; ++ i )
#define foit(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
#define bip system("pause")
#define Int long long
#define pb push_back
#define SZ(X) (int)(X).size()
#define mk make_pair
#define f first
#define s second

int mov[4][2]= { {-1,0},{+1,0},{0,-1},{0,+1} } ;
char grid[60][60];
int n,m,cases;
vector< pair<int,char> > vt;

inline void print(){
    int i,j;
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            cout<<grid[i][j];
        }
        cout<<"\n";
    }
    bip;
}

inline void read(){
    int i,j;
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            cin>>grid[i][j];
        }
    }
}
inline int re(int r, int c, char cc){
    int tot=0;
    stack< pair<int,int> > st;
    st.push( mk(r,c) );
    grid[r][c]='.';
    while( st.empty()==false ){
        pair< int, int > peak = st.top();
        st.pop();
//        grid[peak.f][peak.s]='.';
        ++tot;
            for(int i=0;i<4;++i){
                int tr = peak.f+mov[i][0];
                int tc = peak.s+mov[i][1];
                if( tr < 0 || tr >= n || tc <0 || tc >=m )continue;
                if( grid[tr][tc]==cc){
                    grid[tr][tc]='.';
                    st.push( mk(tr,tc) );
                }
            }

    }
    //cout<<cc<<" "<<tot<<"\n";bip;
return tot;
}
inline bool cmp( pair<int,char> A, pair<int,char> B ){
    if(A.f==B.f){
        return A.s<B.s;
    }
return A.f>B.f;
}
inline void proc(){
    int i,j;
    vt.clear();
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            if( grid[i][j]!='.' ){
                char ch = grid[i][j];
                int tot = re(i,j,ch);

                vt.pb( mk(tot,ch) );
            }
        }
    }
    sort( vt.begin(), vt.end(), cmp );
    printf("Problem %d:\n",cases);
    for(i=0;i<SZ(vt);++i){
        printf("%c %d\n",vt[i].s,vt[i].f);
    }
}

inline void doRest( int cases ){
    read();
    proc();
}
int main(){
    cases=1;
    while( scanf("%d %d",&n,&m)==2 ){
        if( !n && !m )break;
        doRest(cases);
        ++cases;
    }

return 0;
}

